import {
  AmcaxForm,
  BaseCommand,
  CommandDialog,
  ConstraintType,
  CurveType,
  ILineParams,
  MathTool,
} from '@amcax/base';
import {
  SKETCH_CENTEREVENTS,
  sketchEventCenter,
} from '@app-cad/environments/nextcad/events/SketchEventCenter';
import './index.scss';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';
import i18n from 'i18next';
import { useEffect, useRef, useState } from 'react';

// import { Input, Divider, Checkbox, InputNumber } from 'antd';
import CmdInteractor from './CmdInteractor';
import {
  Constraint,
  ExtrudeDialogProps,
  labelValues,
  LinePickEve,
  PlainOptions,
} from './types';

type iterate<U extends CurveType> = {
  [key in U]: string;
};
// 不同线段对应的label
const LineMapLabel: Partial<iterate<CurveType>> = {
  Point: 'point',
  Line: 'line',
  Circle: 'circle',
  ArcOfCircle: 'arc',
  Ellipse: 'ellipse',
  Bspline: 'bspline',
};

function LineDialog({ title, onClose }: ExtrudeDialogProps) {
  const [titleEdit, setTitleEdit] = useState(title);
  const cmdRef = useRef<CmdInteractor>(null);
  // 添加约束
  const [constraint, setConstraint] = useState<Constraint>({
    nowGeoRelation: [],
    geoRelation: null,
    select: null,
    lineLength: null,
    lineAngle: null,
  });

  useEffect(() => {
    cmdRef.current = new CmdInteractor();
    cmdRef.current.addExit(onClose);
    sketchEventCenter().on(LinePickEve.SKETCH_SELECT_PICK, pickSelectInfo);
    sketchEventCenter().on(SKETCH_CENTEREVENTS.MOUSEDOWNMOVE, () => {
      onClose();
    });
    return () => {
      onBlur();
      sketchEventCenter().off(LinePickEve.SKETCH_SELECT_PICK, pickSelectInfo);
      cmdRef.current?.destroy();
      cmdRef.current = null;
    };
  }, []);
  // 检测到线段选中信息
  const onSelectLineIndo = (data) => {
    setTitleEdit(
      i18n.t('command.' + LineMapLabel[cmdRef.current.pickedCurve.type]),
    );
    constraint.select = [cmdRef.current.pickedCurve.curveStyle];
    if (data.lineLength) {
      data.lineLength = MathTool.fixNumber(data.lineLength, 6);
    }
    if (data.lineAngle) {
      data.lineAngle = MathTool.fixNumber(data.lineAngle, 6);
      if (data.lineAngle === 360) {
        data.lineAngle = 0;
      }
    }
    setConstraint((state) => ({
      ...state,
      ...data,
      nowGeoRelation: cmdRef.current.pickedCurve.constraints.map((item) =>
        item.type.toString(),
      ),
    }));
  };
  const pickSelectInfo = (data) => {
    if (data?.id) {
      // 选中线段
      cmdRef.current.setPickedCurve(data);
    } else {
      onClose();
    }
  };

  const onChange = (data) => {
    // 修改成构造线或者实线
    if (constraint.select[0] !== data.formData.select[0]) {
      editCurveStyle(data.formData.select);
    }
    setConstraint((state) => ({ ...state, ...data.formData }));
  };

  const onFocus = (key: string) => {
    const params: typeof constraint = { ...constraint };
    if (key === 'root_lineAngle') {
      params.geoRelation = ConstraintType.Angle;
    }
    if (key === 'root_lineLength') {
      params.geoRelation = ConstraintType.Dimension;
    }
    setConstraint(params);
  };

  useEffect(() => {
    cmdRef.current.constraint = MathTool.deepClone(constraint);
    sketchEventCenter().on(LinePickEve.SKETCH_LINE_INFO, onSelectLineIndo);
    return () => {
      sketchEventCenter().off(LinePickEve.SKETCH_LINE_INFO, onSelectLineIndo);
    };
  }, [constraint]);

  const onBlur = () => {
    cmdRef.current.addConstraint();
    setConstraint((state) => ({ ...state, geoRelation: null }));
  };

  const editCurveStyle = (select: string[]) => {
    let param = null;
    if (cmdRef.current.pickedCurve.type === 'Line') {
      const { point1, point2 } = cmdRef.current.pickedCurve
        .params as ILineParams;
      param = {
        point1,
        point2,
      };
    } else {
      param = {};
    }
    cmdRef.current.coreEditLine({
      curveStyle: select && select.length > 0 ? select[0] : 0,
      ...param,
    });
  };
  return (
    <CommandDialog
      title={titleEdit + '(属性)'}
      onClose={onClose}
      placement='topLeft'
    >
      <AmcaxForm
        schema={
          cmdRef.current?.pickedCurve?.type === 'Line' ? schemaLine : schema
        }
        uiSchema={uiSchema}
        validator={validator}
        onChange={onChange}
        onFocus={onFocus}
        onBlur={onBlur}
        formData={{
          nowGeoRelation: constraint.nowGeoRelation,
          select: constraint.select,
          lineLength: constraint.lineLength,
          lineAngle: constraint.lineAngle,
        }}
      />
    </CommandDialog>
  );
}

export const lineAttribute: BaseCommand = {
  id: 'EditLine',
  label: 'command.line',
  icon: 'commands/feature/line',
  group: 'sketch',
  create: function (label: string, onClose: () => void) {
    return (
      <LineDialog
        title={i18n.t(label)}
        onClose={onClose}
      />
    );
  },
};

const uiSchema: UiSchema = {
  nowGeoRelation: {
    'ui:enumDisabled': Object.keys(labelValues),
  },
  lineLength: {
    'ui:disabled': false,
  },
  lineAngle: {
    'ui:disabled': false,
  },
  select: {
    'ui:widget': 'checkboxes',
    'ui:classNames': 'guide',
  },
  'ui:options': {
    classNames: 'cmd-sketch__cmd-editLine',
    submitButtonOptions: {
      norender: true,
    },
    inline: true,
  },
};

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    nowGeoRelation: {
      type: 'array',
      title: '现有几何关系(E)',
      items: {
        type: 'string',
        oneOf: Object.keys(labelValues).map((key) => ({
          title: labelValues[key],
          const: key,
        })),
      },
      uniqueItems: true,
    },
    select: {
      type: 'array',
      title: '选项(O)',
      items: {
        type: 'number',
        oneOf: [{ title: '作为构造线(C)', const: PlainOptions.Construction }],
      },
      uniqueItems: true,
    },
  },
};
const schemaLine: RJSFSchema = {
  type: 'object',
  properties: {
    ...schema.properties,
    // lineLength: { type: 'number', title: '长度', default: null },
    // lineAngle: { type: 'number', title: '角度', default: null },
  },
};
